import Layers from "../layers/index";
import AsyncValidator from "async-validator";
import FormInput from "./form-input";
import {messages} from "./messages.js";

/**
 * 表单校验器
 */
class Validator {
    /**
     * 比较当前值是否有效，错误信息会直接赋值到 this.message
     *
     * @param input {FormInput} - 表单组件对象实体
     * @returns {boolean} 数据校验是否通过
     */
    checkValidity(input: FormInput) {
        let name = input.name, label = input.label, value = input.value;
        let res = true;
        // require 验证单独封装，require 是很特殊的校验，与 H5 默认功能挂钩，
        // require 设置为 true 的情况下，某些项目可能要求增加一个小红点，目前版本没有这个设计。
        if (input.require === true) {
            if (Layers.isEmpty(value)) {
                input.message = '[' + label + ']不允许为空！';
                res = false;
            }
        }
        // Validator 验证
        if (res === true && input.rules !== undefined) {
            this.checkValidityWithAsyncValidator(input.rules, value, label, (errors, invalidFields) => {
                res = !errors;
                //错误提示，这里只取第一个
                input.message = errors ? errors[0].message : '';
            }).then(values => {
                console.log(values);
            });
        }
        input.valid = res;
        return res;
    }

    /**
     * 使用 AsyncValidator 进行数据校验，代码参考自 element-ui
     *
     * @param rules 数据校验规则
     * @param value 需要验证的值
     * @param label 提示用的标签值
     * @param call 数据校验回调函数
     * @return Promise<Values>
     */
    checkValidityWithAsyncValidator(rules, value, label, call) {
        // 规则描述
        const descriptor = {};
        if (Layers.isNotEmpty(rules)) {
            rules.forEach(rule => {
                delete rule.trigger;
            });
        }
        descriptor[label] = rules;

        // 数据模型
        const validator = new AsyncValidator(descriptor);
        const model = {};
        model[label] = value;

        // 导入汉化之后的错误提示包
        validator.messages(messages);

        // 数据校验，这里忽略返回值
        return validator.validate(model, {firstFields: true}, call)
    }
}

export default Validator;